package com.kingcore.director.search.ui;




import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.Token;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexModifier;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.RAMDirectory;
import org.mira.lucene.analysis.MIK_CAnalyzer;

import com.kingcore.director.DirectorContext;


/**
 * 创建新的索引
 * @author HJ
 * 
 */ 
public class LocalFileIndexBuilder {
	private int mergeFactor = 100000;//每添加100个document合并成一个segament,100个segamengt合并成一个segament,确保索引中segament数不超过100,值越大,查询越慢
	private int maxMergeDocs = 100000;//每个segament的document数不超过10000
	private int minMergeDocs = 10000;
	private int maxBufferedDocs = 100000;//在合并前缓存多少个document
	private int fieldLength = Integer.MAX_VALUE;//每个field能索引的最大term(词)数
//	public static Analyzer analyzer = new MIK_CAnalyzer();
//	public static Analyzer analyzer = new StandardAnalyzer();
	private Analyzer analyzer;
	private RAMDirectory rDir;
	private FSDirectory fDir;
	private IndexWriter ramWriter;
	private IndexWriter fsWriter;
	private boolean overWrite = false;
	public static int RAMLIMIT = 100;
	public static Analyzer ANALYZER = new LocalFileAnalyzer();
	public static Analyzer ANALYZER1 = new StandardAnalyzer();
	public static Analyzer ANALYZER2 = new MIK_CAnalyzer();
	//索引保存路径
//	public static String MAIN_STOREPATH = IndexBuilder.class.getResource("").getPath() + "index/";
	public static String MAIN_STOREPATH = DirectorContext.getAppTmpDir()
									   +File.separator+"index"+File.separator;
	public static String USER_INDEX = MAIN_STOREPATH + "user/";  //用户索引路径
	public static String GROUP_INDEX = MAIN_STOREPATH + "group/";  //群索引路径
	public static String ACTIVE_INDEX = MAIN_STOREPATH + "active/";  //活动索引路径
	public static String DIARY_INDEX = MAIN_STOREPATH + "diary/";  //日记索引路径
	public static String WISH_INDEX = MAIN_STOREPATH + "wish/";  //愿望索引路径
	public static String PIC_INDEX = MAIN_STOREPATH + "pic/";  //图片索引路径
	public static String LocalFileSystem_INDEX = MAIN_STOREPATH + "localFileSystem/"; //微博客搜索索引

	public static String DELIMETER = "#deli";
	
	public static String IndexFieldName = "id";
	public static String Field_For_Index = "m1";
	/** 不被索引的列: 实时消息对象ID(objId) 来自(comeFrom) 对象类型ID(objTypeId) 发布时间中文(publishDate)
	 *  发布时间数字显示(publishDate1) 发布时间日期类型(broadcastDate) 发布所属对象id(broadcasterId)
	 *  发布人id(ui) 回复数(replyCount) 动作类型中文(actName) 对象类型中文(objType) 发布人昵称(un)
	 *  发布微博客上传的图片(image) 发布人头像(um) 微博客打的标签(tagId)*/
	public static String Field_Not_Index = "m2";

	static{
		String className = LocalFileIndexBuilder.class.getName();
        try {
          LocalFileIndexBuilder.class.getClassLoader().loadClass(LocalFileIndexBuilder.class.getName());
        } catch (ClassNotFoundException e) {
          throw new RuntimeException("class not found '"+className+"'", e);
        }
	}
	
	private LocalFileIndexBuilder(Analyzer analyzer, String indexPath, boolean overWrite) {
		this.analyzer = analyzer;
		this.overWrite = overWrite;
		this.init(indexPath);  // call alone
	}
	
	private static LocalFileIndexBuilder instance = null;
	public static LocalFileIndexBuilder getInstance(Analyzer analyzer, String indexPath, boolean overWrite){
//		if (instance==null) {
			instance = new LocalFileIndexBuilder(analyzer, indexPath, overWrite);
//		}
		return instance;
	}
	
	/**
	 * 打开一个文件索引
	 *
	 */
	public void init(String indexPath) {		
		try {
			System.out.println(indexPath);
			this.fDir = openFSDirectory(indexPath);
			this.buildDiskWriter();
		} catch (IOException e) {
			System.err.println("Fail to open a index!");
			e.printStackTrace();
		}
	}
	
	/**
	 * 读取指定路径的文件的索引
	 * @param indexSavePath
	 * @param overwrite 是否覆盖现有索引
	 * @return
	 * @throws IOException
	 */
	private FSDirectory openFSDirectory(String indexPath) throws IOException {
		return FSDirectory.getDirectory(indexPath, overWrite);
	}
	
	/**
	 * 新增一个内存的索引
	 * @return
	 */
	private RAMDirectory openRAMDirectory() {
		return new RAMDirectory();
	}
	
	/**
	 * 建索引的参数设置
	 * @param writer
	 * @throws IOException
	 */
	private void setFactors() throws IOException {
		fsWriter.setMergeFactor(this.mergeFactor);
		fsWriter.setMaxFieldLength(this.fieldLength);
		fsWriter.setMaxMergeDocs(maxMergeDocs);
		fsWriter.setMaxBufferedDocs(this.maxBufferedDocs);   
	}
	
	/**
	 * 创建基于文件的IndexWriter
	 * @param overwrite
	 * @param indexSavePath
	 * @throws IOException
	 */
	private void buildDiskWriter() throws IOException {
		fsWriter = new IndexWriter(fDir, analyzer, overWrite); //overWrite
		this.setFactors();
	}
	
	/**
	 * 创建内存的writer
	 * @param overwrite
	 * @throws IOException
	 */
	private void buildRAMWriter() throws IOException {
		if(ramWriter == null) {
			ramWriter = new IndexWriter(rDir, analyzer, true);
		} else {
			ramWriter.close();
			ramWriter = new IndexWriter(rDir, analyzer, true);
		}
	}

	/**
	 * 保存要建索引的数据到索引
	 * @param documents
	 */
	public void writeToIndex(List<Document> documents) {
		writeIn(documents);
	}

	private void writeIn(List<Document> documents) {
//		int i = 0;
		Iterator it = documents.iterator();
		try {
			while(it.hasNext()) {
				fsWriter.addDocument((Document) it.next());
			}
		} catch (Exception e) {
			System.err.println("Error occurred when writing document");
			e.printStackTrace();
		} finally {
			try {
				fsWriter.optimize();
//				this.fDir.close();
//				this.fsWriter.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		documents.clear();
	}
	
	public void close(){
		try { 
			this.fDir.close();
			this.fsWriter.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 判断索引文件夹里是否已经有创建了的索引
	 * @param indexPath
	 * @return
	 */
	public static boolean ifIndexExist(String indexStorePath) {
		boolean ret = false;
		File f = new File(indexStorePath);
		if(f.exists()) {
			if(f.isDirectory()) {
				if(f.listFiles().length > 0) {
					ret = true;
				}
			}
		}
		return ret;
	}
	
	public static void main(String args[]) {
		
		
	}
	
	 public static void outputAnalyzer(Analyzer a ,String input) throws Exception{
		   TokenStream ts = a.tokenStream("dummy",new StringReader(input));
		   StringReader readerInput = new StringReader(input);
		   while(true){
		     Token t = ts.next();
		     if(t!=null){
		       System.out.print(t.termText());
		       System.out.print(" ");
		     }
		     else
		     break;

		   }
		 System.out.println(" ");
		 ts.close();
	}

	public void addDocumet(Document doc) { 
		IndexModifier indexModifier = null;
		  try {
			  indexModifier = new IndexModifier(this.fDir,  this.analyzer,
				        this.overWrite );
			  indexModifier.addDocument(doc);
		  } catch (IOException e) {
		    e.printStackTrace();
		  } finally {
			  try {
				indexModifier.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			  this.fDir.close();
		  }
	}

}
